# uncompyle6 version 3.2.3
# Python bytecode 3.6 (3379)
# Decompiled from: Python 3.6.8 |Anaconda custom (64-bit)| (default, Feb 21 2019, 18:30:04) [MSC v.1916 64 bit (AMD64)]
# Embedded file name: site-packages\sqlalchemy\util\compat.py
"""Handle Python version/platform incompatibilities."""
import sys
from contextlib import contextmanager

try:
    import threading
except ImportError:
    import dummy_threading as threading

py36 = sys.version_info >= (3, 6)
py33 = sys.version_info >= (3, 3)
py32 = sys.version_info >= (3, 2)
py3k = sys.version_info >= (3, 0)
py2k = sys.version_info < (3, 0)
py265 = sys.version_info >= (2, 6, 5)
jython = sys.platform.startswith("java")
pypy = hasattr(sys, "pypy_version_info")
win32 = sys.platform.startswith("win")
cpython = not pypy and not jython
import collections

next = next
if py3k:
    import pickle
else:
    try:
        import cPickle as pickle
    except ImportError:
        import pickle

    if py265:
        safe_kwarg = lambda arg: arg
    else:
        safe_kwarg = str
    ArgSpec = collections.namedtuple(
        "ArgSpec", ["args", "varargs", "keywords", "defaults"]
    )
    if py3k:
        import builtins
        from inspect import getfullargspec as inspect_getfullargspec
        from urllib.parse import quote_plus, unquote_plus, parse_qsl, quote, unquote
        import configparser
        from io import StringIO
        from io import BytesIO as byte_buffer

        def inspect_getargspec(func):
            return ArgSpec(*inspect_getfullargspec(func)[0:4])

        string_types = (str,)
        binary_types = (bytes,)
        binary_type = bytes
        text_type = str
        int_types = (int,)
        iterbytes = iter

        def u(s):
            return s

        def ue(s):
            return s

        def b(s):
            return s.encode("latin-1")

        if py32:
            callable = callable
        else:

            def callable(fn):
                return hasattr(fn, "__call__")

        def cmp(a, b):
            return (a > b) - (a < b)

        from functools import reduce

        print_ = getattr(builtins, "print")
        import_ = getattr(builtins, "__import__")
        import itertools

        itertools_filterfalse = itertools.filterfalse
        itertools_filter = filter
        itertools_imap = map
        from itertools import zip_longest
        import base64

        def b64encode(x):
            return base64.b64encode(x).decode("ascii")

        def b64decode(x):
            return base64.b64decode(x.encode("ascii"))

    else:
        from inspect import getargspec as inspect_getfullargspec

        inspect_getargspec = inspect_getfullargspec
        from urllib import quote_plus, unquote_plus, quote, unquote
        from urlparse import parse_qsl
        import ConfigParser as configparser
        from StringIO import StringIO
        from cStringIO import StringIO as byte_buffer

        string_types = (basestring,)
        binary_types = (bytes,)
        binary_type = str
        text_type = unicode
        int_types = (int, long)

        def iterbytes(buf):
            return (ord(byte) for byte in buf)

        def u(s):
            return unicode(s, "utf-8")

        def ue(s):
            return unicode(s, "unicode_escape")

        def b(s):
            return s

        def import_(*args):
            if len(args) == 4:
                args = args[0:3] + ([str(arg) for arg in args[3]],)
            return __import__(*args)

        callable = callable
        cmp = cmp
        reduce = reduce
        import base64

        b64encode = base64.b64encode
        b64decode = base64.b64decode

        def print_(*args, **kwargs):
            fp = kwargs.pop("file", sys.stdout)
            if fp is None:
                return
            for arg in enumerate(args):
                if not isinstance(arg, basestring):
                    arg = str(arg)
                fp.write(arg)

        import itertools

        itertools_filterfalse = itertools.ifilterfalse
        itertools_filter = itertools.ifilter
        itertools_imap = itertools.imap
        from itertools import izip_longest as zip_longest
    import time

    if win32 or jython:
        time_func = time.clock
    else:
        time_func = time.time
    from collections import namedtuple
    from operator import attrgetter as dottedgetter

    if py3k:

        def reraise(tp, value, tb=None, cause=None):
            if cause is not None:
                if not cause is not value:
                    raise AssertionError("Same cause emitted")
                value.__cause__ = cause
            if value.__traceback__ is not tb:
                raise value.with_traceback(tb)
            raise value

    else:
        exec(
            "def reraise(tp, value, tb=None, cause=None):\n    if cause is not None:\n        assert cause is not value, 'Same cause emitted'\n    raise tp, value, tb\n"
        )

    def raise_from_cause(exception, exc_info=None):
        if exc_info is None:
            exc_info = sys.exc_info()
        exc_type, exc_value, exc_tb = exc_info
        cause = exc_value if exc_value is not exception else None
        reraise(type(exception), exception, tb=exc_tb, cause=cause)

    if py3k:
        exec_ = getattr(builtins, "exec")
    else:

        def exec_(func_text, globals_, lcl=None):
            if lcl is None:
                exec("exec func_text in globals_")
            else:
                exec("exec func_text in globals_, lcl")

    def with_metaclass(meta, *bases):
        """Create a base class with a metaclass.
        
        Drops the middle class upon creation.
        
        Source: http://lucumr.pocoo.org/2013/5/21/porting-to-python-3-redux/
        
        """

        class metaclass(meta):
            __call__ = type.__call__
            __init__ = type.__init__

            def __new__(cls, name, this_bases, d):
                if this_bases is None:
                    return type.__new__(cls, name, (), d)
                else:
                    return meta(name, bases, d)

        return metaclass("temporary_class", None, {})

    @contextmanager
    def nested(*managers):
        """Implement contextlib.nested, mostly for unit tests.
        
        As tests still need to run on py2.6 we can't use multiple-with yet.
        
        Function is removed in py3k but also emits deprecation warning in 2.7
        so just roll it here for everyone.
        
        """
        exits = []
        vars = []
        exc = (None, None, None)
        try:
            for mgr in managers:
                exit = mgr.__exit__
                enter = mgr.__enter__
                vars.append(enter())
                exits.append(exit)

            yield vars
        except:
            exc = sys.exc_info()
        finally:
            while exits:
                exit = exits.pop()
                try:
                    if exit(*exc):
                        exc = (None, None, None)
                except:
                    exc = sys.exc_info()

            if exc != (None, None, None):
                reraise(exc[0], exc[1], exc[2])
